#include "linkedlist.h"
#include <stdarg.h>
#include <stdio.h>

linkedlist* create_list() {
    linkedlist* list = (linkedlist*)malloc(sizeof(linkedlist));
    if (list == NULL) {
        return NULL;
    }
    listnode* head = (listnode*)malloc(sizeof(listnode));
    if (head == NULL) {
        free(list);
        return NULL;
    }
    head->next = NULL;
    list->length = 0;
    list->head   = head;

    return list;
}

void free_list(linkedlist* list) {
    assert(list != NULL);
    // free(list); // ❌  只会释放结构体的内存，每个节点占用的内存并没有释放
    // 正确的做法：一遍遍历一编删除
    listnode* current = list->head;
    while(current != NULL)
    {
        listnode* next = current->next;
        free(current);
        current = next;
    }
    free(list);
}

void visit_list(linkedlist* list, void (*callback)(int)) {
    assert(list != NULL);

    listnode* p = list->head->next;
    while(p) {
        callback(p->val);
        p = p->next;
    }
}

void insert(linkedlist* list, listnode* p, int val) {
    // TODO 修改指针的操作，请学员结合ppt中的图补齐此处的逻辑
    listnode* new_node = (listnode*)malloc(sizeof(listnode));
    assert(new_node != NULL);
    new_node = val;
    new_node->next = NULL;//创建新节点

    listnode* current_node = list->head;
    while(current_node != NULL)
    {
        if(&(current_node->next) == p)
        {
            new_node->next = current_node->next;
            current_node->next = new_node;
            return;
        }
        current_node = current_node->next;
    }

}

void remove(linkedlist* list, listnode* p) {
    // TODO 修改指针的操作，请学员结合ppt中的图补齐此处的逻辑
    // 1. 先找到待删除元素p的前驱节点
    // 2. 修改指针
    assert(list != NULL);
    assert(p != NULL);
   

    if(list->head == p)
    {
        list->head = p->next;
        free(p);
        return;
    }

    listnode* prev = list->head;

    while(prev != NULL && prev->next != p){
        prev = prev->next;
    }

//找到前躯节点
    if(prev != NULL)
    {
        prev->next = p->next;
        p->next = NULL;
        free(p);
    }
    

}